<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    // 自定义构造函数  => 面向对象的封装

    // 2. 函数版(简易工厂模式)
    // 优点 => 可以根据给定参数快速生成对
    // 缺点:
    // 1. 通过函数创建的对象和函数没有关系  => 不是通过构造函数创建的
    // 2. 公有的属性和方法重复声明 => 占内存

    // var arr = new Array(1,2,3,4);
    // console.log(arr);
    // var obj = new Object({a:1,b:2});
    // console.log(obj);
    // var s = new Set([1,1,2,3,1,2]);
    // console.log(s);

    // String  Number  Boolean  
    // 1. 作为普通函数使用  => 强制类型转换
    // console.log(String(100));
    // console.log(Number(100));
    // console.log(Boolean(100));

    // 2. 作为构造函数使用  => 创建实例化对象
    // console.log(new String(100));   
    // console.log(new Number(100));
    // console.log(new Boolean(100));

    // 对比普通函数和构造函数,我们发现构造函数就是在调用时多了个关键词  new 

    // 实例化 => 实例化是指在面向对象的编程中，把用类(构造函数)创建对象的过程称为实例化 (new Xxx)
    // 实例化对象 =>  被创建的对象就称之为 实例化对象 (实例/对象)
    
    // new 关键词做了哪些操作? 
    // 1. 创建一个纯净的实例化对象
    // 2. 给实例化对象绑定原型属性([Prototype]),指向构造函数的原型对象(Cat.prototype) => 浅复制,引用同一片内存空间 
    //    所有的实例化对象都可以通过原型属性([Prototype]),访问构造函数构造函数的原型对象(Cat.prototype)   
    // 3. 强制将this指向被创建的实例化对象
    // 4. 默认返回被创建的实例化对象

    // 注意:
    // 1. 构造函数中的this,指向本次构造函数执行过程中创建的实例化对象 (每次调用都会创建新的实例化对象)
    // 2. 为了区分普通函数和构造函数 => 要求构造函数首字符大写
    // 3. 每次调用构造函数 都会执行构造函数的上下文 => 实例化对象
    // 4. 所有的实例化对象都可以通过原型属性([Prototype]),访问构造函数构造函数的原型对象(Cat.prototype)

    // 1. 作为普通函数使用
    // function fn(){
    //     console.log("fn被调用了");
    //     console.log("this",this); // this -> window
    // }

    // var result = fn();
    // console.log("返回值",result);  // undefined


    // 2. 作为构造函数使用  => 创建实例化对象
    function Fn(x,y){
        // {}    创建一个纯净的实例化对象
        // {}[[Prototype]] = Fn.prototype;
        // this -> {}  强制将this指向被创建的实例化对象

        console.log("fn被调用了");
        console.log("this",this); // this -> {}
        console.log(this instanceof Fn);  // true

        // 我们在自定义构造函数过程中 所做的操作  => 将属性和方法通过this绑定到实例化对象上

        this.x = x;
        this.y = y;
        this.toString = function(){
            return `(${this.x},${this.y})`; //  "(10,20)"
        }

        // return this;  默认返回被创建的实例化对象
    }

    // 创建一个实例化对象 => 赋值给变量result 
    var result = new Fn(10,20);
    console.log("返回值",result);  // undefined

    console.log(result.x);
    console.log(result.y);
    console.log(result.toString());


    // var result = new Fn(10,20);
    // console.log("返回值",result);  // undefined






</script>
</html>